--- import type { GetStaticPaths } from 'astro'; import { getCollection } from 'astro:content'; import { shouldShowPost, getPostSlug } from '@/utils/markdown'; import PostLayout from '@/layouts/PostLayout.astro'; export const getStaticPaths: GetStaticPaths = async () => { // Get all posts const posts = await getCollection('posts'); // Filter posts for production (in dev, show all including drafts) const isDev = import.meta.env.DEV; const visiblePosts = posts.filter(post => shouldShowPost(post, isDev)); // Generate paths for new slugs const paths = visiblePosts.map(post => ({ params: { slug: getPostSlug(post) }, props: { post, isCanonical: true } })); // Generate paths for old IDs (if different) to handle redirects // This prevents broken links for existing posts const redirectPaths = visiblePosts .filter(post => getPostSlug(post) !== post.id) .map(post => ({ params: { slug: post.id }, props: { post, isCanonical: false } })); return [...paths, ...redirectPaths]; }; export interface Props { post: any; isCanonical?: boolean; } const { post, isCanonical = true } = Astro.props; // Perform 301 redirect if accessed via old ID-based URL if (!isCanonical) { return Astro.redirect(`/posts/${getPostSlug(post)}`, 301); } // Validate post data if (!post) { return Astro.redirect('/404'); } // Check if post should be visible in production const isDev = import.meta.env.DEV; if (!shouldShowPost(post, isDev)) { return Astro.redirect('/404'); } ---